"""
使用适配器模式来完成网络读写操作
"""
import logging
from asyncio import StreamReader, StreamWriter


class ReaderAdapter:
    """
    适配器模式的基类
    所有网络协议的读取基类.
    """

    async def read(self, n=-1) -> bytes:
        """
        读取 n 个字节，乳沟 n 没有给出或者等于-1,则读取到EOF停止.
        :return: 返回读到的字节
        """

    def feed_eof(self):
        """读到eof为止"""


class WriterAdapter:
    """
    适配器模式的基类
    所有网络协议的写入基类.
    """

    def write(self, data):
        """将数据写入到协议层"""

    async def drain(self):
        """刷新写缓冲区"""

    def get_peer_info(self):
        """返回socket的信息"""

    async def close(self):
        """关闭协议连接"""


class StreamReaderAdapter(ReaderAdapter):
    """
    Asyncio Streams 读取
    """
    def __init__(self, reader: StreamReader):
        self._reader = reader

    async def read(self, n=-1) -> bytes:
        if n == -1:
            data = await self._reader.read(n)
        else:
            data = await self._reader.readexactly(n)
        return data

    def feed_eof(self):
        return self._reader.feed_eof()


class StreamWriterAdapter(WriterAdapter):
    """Asyncio Streams 写入"""
    def __init__(self, writer: StreamWriter):
        self.logger = logging.getLogger(__name__)
        self._writer = writer

    def write(self, data):
        self._writer.write(data)

    async def drain(self):
        await self._writer.drain()

    def get_peer_info(self):
        extra_info = self._writer.get_extra_info('peername')
        return (extra_info[0], extra_info[1])

    async def close(self):
        await self._writer.drain()
        if self._writer.can_write_eof():
            self._writer.write_eof()
        self._writer.close()
